
import chisel3._
import chisel3.util._
import chiseltest._
import org.scalatest.{Matchers, FlatSpec}
import scala.util.Random

import comlib._
import comlib.util._

class UtilSpec extends FlatSpec with ChiselScalatestTester with Matchers {

  behavior of "oneNumber"

  it should "支持“1”个数统计" in {

    test( new Module{
      val io = IO( new Bundle{
        val in1 = Input(UInt(8.W))
        val out1 = Output(UInt())
      } )

      io.out1 := oneNumber( io.in1 )

    } ){ dut =>

      val result = Seq(
        "b0000_0000".U -> 0.U,
        "b0000_0001".U -> 1.U,
        "b0010_0000".U -> 1.U,
        "b1000_0000".U -> 1.U,
        "b0010_1000".U -> 2.U,
        "b0010_1001".U -> 3.U,
        "b1010_1001".U -> 4.U,
        "b1111_1111".U -> 8.U,
        "b1111_1011".U -> 7.U,
      )

      for( (in, out) <- result ){
        dut.io.in1.poke( in )
        dut.io.out1.expect( out, f"Input is ${in}" )
      }

    }

  }

}

class SliceSetSpec extends FlatSpec with ChiselScalatestTester with Matchers {

  it should "支持UInt=>UInt赋值" in {
    test( new Module{
      val io = IO(new Bundle{
        val in = Input(UInt(8.W))
        val out = Output(UInt(16.W))
        val iout = Input(UInt(16.W))
      })
      io.out := fillSlice( io.iout, io.in, 10, 3 )
    } ){dut =>

      val result = Seq(
        ("b10000_00000000_001".U, "b1010_1010".U) -> "b10000_10101010_001".U,
      )

      for( ((iout, in), out) <- result ){
        dut.io.iout.poke( iout )
        dut.io.in.poke( in )
        dut.io.out.expect( out, f"in=${in} iout=${iout}" )
      }

    }
  }

}

class GroupSpec extends FlatSpec with ChiselScalatestTester with Matchers {

  it should "支持UInt分组为UInt" in {
    test( new Module {
      val io = IO(new Bundle{
        val in = Input(UInt(32.W))
        val out = Output(Vec(4, UInt()))
      })
      io.out := group( 0.U(8.W), io.in, Fill0 )
    } ){dut =>
    
      val result = Seq(
        "b10100101_11110000_00110011_00001111".U -> Seq("b00001111".U, "b00110011".U, "b11110000".U, "b10100101".U),
        "b11111111_11110000_00000000_00001111".U -> Seq("b00001111".U, "b00000000".U, "b11110000".U, "b11111111".U),
      )

      for( (in, out) <- result ){
        dut.io.in.poke( in )
        for( i <- 0 until 4 )
          dut.io.out(i).expect( out(i) )
      }
    
    }
  }

}
